/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import util.print.printLogCat;

/**
 * 字节操作工具类 它是一个单例
 *
 * @author 梁前武 QQ1587790525
 */
public class byteTools {
    private static byteTools _instance=null;
    
    //单例静态工厂方法,同步防止多线程环境同时执行 
     synchronized public static byteTools getInstance(){
     if(_instance==null){
     _instance=new byteTools();
     }
     return _instance;
     }
      /**
     * 向数组指定地址写入一个字节
     * @param d 字节数组
     * @param data 写入字节
     * @param str  写入地址
     * @return 0成功 1失败
     */
    public static  int  writeAtByte(byte[] d, byte data, int str) {
        if(!check.checkObjectEixst(d)){
        return 1;
        }
       if(d.length>str){
           d[str]=data;
        return 0;
       }
        return 1;
        
    }
    /**
     * 将b2中的数据写入从地址str开始的数组b1中
     * 如果b1或b2为null将失败
     *
     * @param b1
     * @param b2
     * @param str
     * @param type 写入方式 0 如果b1剩余长度不都将自动舍弃b2剩余的数据
     * 1  如果b1剩余长度不都将自动增长b1的长度将b2数据放完
     * @return 0成功 1失败
     */
    public static int writeByte1ToByte2(byte[] b1, int str, byte[] b2, int type) {
       if(!check.checkObjectEixst(b1)||!check.checkObjectEixst(b2)){
        return 1;
        }
        if(b1.length>str){
        switch(type){
            case 0:
            int index2=0;
        for(int i=str;i<b1.length;i++){
        if(index2>=b2.length)
            break;
        b1[i]=b2[index2];
        index2++;
        }
                break;
            case 1:
                if(b1.length>=str+b2.length){
            writeByte1ToByte2(b1,str,b2,0);//下标不会溢出
                  
            }else{
            byte[] b3=new byte[str+b2.length];//初始化一个新的数组是两个原始数组的总长
            System.arraycopy(b1,0, b3, 0,str);//将b1的数据复杂到b3中
            System.arraycopy(b2,0, b3, str,b2.length);//将b2总的数据复制到b3中
            b1=null;
            b1=b3;
            }
            break;
        }
        return 0;
        }
        return 1;
        
    }
    /**
      * 将a1和a2组合为一个数组
      * 如果 a1存在a2为null将返回a1 
      * 如果a1为null 将返回a2 而不管a2是否为null
      * @param a1
      * @param a2
      * @return 
      */
    public static byte[] combinArrays(byte[] a1, byte[] a2) {
        ///throw new UnsupportedOperationException("Not supported yet.");
        if(!check.checkObjectEixst(a1)){
        return a2;
        }
        if(!check.checkObjectEixst(a2)){
        return a1;
        }
        byte[] a3=new byte[a1.length+a2.length];
        System.arraycopy(a1,0, a3,0, a1.length);
        System.arraycopy(a2,0, a3,a1.length, a2.length);
        
        return a3;
    }
    
    public static boolean compareArrays(byte[] a1, byte[] a2){
        if(!check.checkObjectEixst(a1)||!check.checkObjectEixst(a2)){
            printLogCat.printlnWriter("can,t compareArrays exist null Arrays");
            return false;
        }
        if(a1.length!=a2.length){
            printLogCat.printlnWriter("can,t compareArrays length is no equal");
            return false;
        }
        int i=0;
        for(i=0;i<a1.length;i++){
        if(a1[i]!=a2[i])break;
        }
        if(i==a1.length){
            printLogCat.printlnWriter("two arrys is equal");
        return true;
        }else{
            printLogCat.printlnWriter("two arrys is inequality");
        return false;
        }
    }
    /**
     * 打印字节数组
     * @param data 
     */
    public static void printBytes(byte[] data){
        if(data==null){
        printLogCat.printlnWriter("can,t print arrys is NULL");
        return;
        }
    for(int i=0;i <data.length;i++){
    printLogCat.printWriter(data[i]+",");
    }
    printLogCat.printlnWriter("");
    }
  
    
    /**
     * 倒换数组 将数组的第一个元素换到最后一个...以此类推
     * 如果  1234 倒换以后为4321
     * @param data 
     * @return null失败
     */
    public static byte[] reverseArray(byte[] data){
       if(!check.checkObjectEixst(data))
           return null;
       byte[] d=new byte[data.length];
       int index=data.length-1;
       for(int i=0;i<data.length;i++){
       d[i]=data[index-i];
       }
       data=null;
       return d;
    }
    
    /**
     * 将byte数组转换为byte类型 
     * 数组长度必须大于0
     * 且返回数组的第一位
     * @return -1失败
     */
    public static byte bytesToByte(byte[] data){
        if(!check.checkObjectEixst(data)){
        throw new java.lang.NullPointerException("can,t bytesToByte Array is no eixte");
        }
        if(data.length<=0){
        throw new java.lang.ArrayIndexOutOfBoundsException("can,t bytesToByte length is no greater 0");
        }
    return data[0] ;
    }
    
    /**      
     * 注释：byte到字节数组的转换！      
     *      
     * @param number 
     * @param length 需要返回的数组长度 必须大于0
     * @return null失败      
     */     
    public static byte[] byteToBytes(byte number,int length) { 
        if(length<=0)
            return null;
        byte[] b = new byte[length];  
        b[0]= number;      
        return b; 
    }
    
    /**
     * 将byte数组转换为int类型 
     * 数组长度只能是 4
     * 且数组的第一位为int的低位 以此类推
     * @return -1失败
     */
    public static int byteToInt(byte[] data){
        if(!check.checkObjectEixst(data)){
       throw new java.lang.NullPointerException("can,t bytesToInt Array is no eixte");
        }
        if(data.length!=4){
       throw new java.lang.ArrayIndexOutOfBoundsException("can,t bytesToInt length is no equal 4");
        }
    return data[0]|data[1]<<8|data[2]<<16|data[3]<<24 ;
    
     /*DataInputStream dis = new DataInputStream(

                                   new ByteArrayInputStream(new byte[]{0,36,0,54}));

                  int i = dis.readInt();

                  System.out.println(i);*/
    }
   
    /**      
     * 注释：int到字节数组的转换！      
     *      
     * @param number      
     * @return      
     */     
    public static byte[] intToByte(int number,int lenght) {   
        int temp = number;
        byte[] b = new byte[4];  
        for (int i = 0; i < b.length; i++) {  
            b[i] = new Integer(temp & 0xff).byteValue(); // 将最低位保存在最低位         
            temp = temp >> 8; // 向右移8位     
        }      
        byte[] len=new byte[lenght];
        for(int i=0;i<lenght;i++){
            len[i]=b[i];
        }
        return len; 
    }
    
  
    /**
     * 将byte数组转换为short类型 
     * 数组长度只能是 2
     * 且数组的第一位为short的低位 以此类推
     * @param data
     * @return  -1失败
     */
    public static short byteToShort(byte[]data) {
    if(!check.checkObjectEixst(data)){
        throw new java.lang.NullPointerException("can,t bytesToShort Array is no eixte");
        }
        if(data.length!=2){
        throw new java.lang.ArrayIndexOutOfBoundsException("can,t bytesToShort length is no equal 2");
        }   
    return (short)(data[0]|data[1]<<8);
    }
   
    /**      
     * 注释：short到字节数组的转换！      
     *      
     * @param s      
     * @return     
     */     
    public static byte[] shortToByte(short number) {   
        int temp = number;
        byte[] b = new byte[2];    
        for (int i = 0; i < b.length; i++) {  
            b[i] = new Integer(temp & 0xff).byteValue();// 将最低位保存在最低位   
            temp = temp >> 8; // 向右移8位       
        }        
        return b;    
    } 
    
    /**
     * long类型转成byte数组 
     * @param number
     * @return 
     */
    public static byte[]longToByte(long number){
        long temp = number;
        
    byte[] b = new byte[8]; 
    for (int i = 0; i < b.length; i++) { 
    b[i] =(byte)new Long(temp & 0xff).longValue(); // 将最低位保存在最低位         
    temp = temp >> 8; // 向右移8位        
    }        
    return b;  
}
    /**
     * 将byte数组转换为Long类型 
     * 数组长度只能是 8
     * 且数组的第一位为Long的低位 以此类推
     * @param data
     * @return  -1失败
     */
     public static long byteToLong(byte[] b) {  
         if(!check.checkObjectEixst(b)){
        throw new java.lang.NullPointerException("can,t bytesToLong Array is no eixte");
        }
        if(b.length!=8){
        throw new java.lang.ArrayIndexOutOfBoundsException("can,t bytesToLong length is no equal 8");
        }
         long s = 0;
         long s0 = b[0] & 0xff;// 最低位   
         long s1 = b[1] & 0xff;     
         long s2 = b[2] & 0xff;   
         long s3 = b[3] & 0xff;   
         long s4 = b[4] & 0xff;// 最低位   
         long s5 = b[5] & 0xff;    
         long s6 = b[6] & 0xff;     
         long s7 = b[7] & 0xff;// s0不变   
         s1 <<= 8;      
         s2 <<= 16;    
         s3 <<= 24;  
         s4 <<= 8 * 4;  
         s5 <<= 8 * 5;    
         s6 <<= 8 * 6;     
         s7 <<= 8 * 7;    
         s = s0 | s1 | s2 | s3 | s4 | s5 | s6 | s7; 
         return s;     }
     /**
      * 字节数组转换工厂，根据数组长度自动转换成相应的类型
      * 但返回的是Long类型，如果要得到更小的类型如果Int
      * 请自己转换
      * @param b 
      */
     public static long bytesToFactory(byte[] b)throws java.lang.ArrayIndexOutOfBoundsException{
         int len=b.length;
         long v = 0;
         switch(len){
                 case 1 :v=bytesToByte(b);break;
                 case 2 :v=byteToShort(b);break;
                 case 4 :v=byteToInt(b);break;
                 case 8 :v=byteToLong(b);break;
                 default:
                     throw new java.lang.ArrayIndexOutOfBoundsException("Array length is no 1,2,4,8");
                 
         }
         return v;
     }

     
          /**
          * 使用Java中流的操作进行int数组到byte数组的转换
          * 
          * @throws IOException
          */
         public static byte[] intsTobytes(int[] d) throws IOException{

                  ByteArrayOutputStream baos = new ByteArrayOutputStream();

                  DataOutputStream dos = new DataOutputStream(baos);
                   for(int i=0;i<d.length;i++)
                  dos.writeInt(d[i]);
                  
                  return baos.toByteArray();
         }
         /**
          * 获取字节里面的指定位的值 
          * @param b
          * @param index 位下标
          * @param len 位的长度
          * @return 
          */
         public static byte getb(byte b,int index,int len){
             byte s=(byte) 0xff;
            switch(len){
                    case 0: s=0; break;
                    case 1: s=1; break; 
                    case 2: s=3; break;
                    case 3: s=7; break;
                    case 4: s=0x0f; break;
                    case 5: s=0x1f; break; 
                    case 6: s=0x3f; break; 
                    case 7: s=0x7f; break;     
            }
            b=(byte) (b>>index);
            b=(byte) (b&s);
            return b;
         }
}
     
